package com.example.antlrdemo.antlr.labeledexpr;

import java.util.HashMap;
import java.util.Map;

/**
 * 自定义访问器
 * 访问器的泛型 为  返回结果 的类型
 */
public class CalculateLabeledExprVisitor extends LabeledExprBaseVisitor<Integer>{

    private Map<String,Integer> memory = new HashMap<>();

    /**
     *  ID '=' expr NEWLINE
     * @param ctx
     * @return
     */
    @Override
    public Integer visitAssign(LabeledExprParser.AssignContext ctx) {
        String id = ctx.ID().getText();   //id在 = 的左侧
        int value = visit(ctx.expr());      //值 在 = 的右侧
        memory.put(id,value);           //将映射关系存在内存中
        return value;
    }

    /**
     * expr NEWLINE
     * @param ctx
     * @return
     */
    @Override
    public Integer visitPrintExpr(LabeledExprParser.PrintExprContext ctx) {
        int value = visit(ctx.expr());  //获取值
        System.out.println( value);  //打印结果
        return 0;               //上面打印出结果，返回假值即可
    }

    @Override
    public Integer visitInt(LabeledExprParser.IntContext ctx) {
        int value = Integer.parseInt(ctx.INT().getText());
        return value;
    }

    @Override
    public Integer visitId(LabeledExprParser.IdContext ctx) {
        String id = ctx.ID().getText();
        if(memory.containsKey(id)) return memory.get(id);
        return 0;
    }

    /**
     *  expr op=('*' | '/') expr
     * @param ctx
     * @return
     */
    @Override
    public Integer visitMulDiv(LabeledExprParser.MulDivContext ctx) {
        int left = visit(ctx.expr(0)); // 左边的值
        int right = visit(ctx.expr(1)); //右边的值
        if(ctx.op.getType()== LabeledExprLexer.Mul){
            return left * right;
        }
        return left / right;
    }

    /**
     * expr ('+' | '-') expr
     * @param ctx
     * @return
     */
    @Override
    public Integer visitAddSub(LabeledExprParser.AddSubContext ctx) {
        int left = visit(ctx.expr(0)); // 左边的值
        int right = visit(ctx.expr(1)); //右边的值
        if(ctx.op.getType()== LabeledExprLexer.Add){
            return left + right;
        }
        return left - right;
    }

    /**
     * '（' expr '）'
     * @param ctx
     * @return
     */
    @Override
    public Integer visitPanens(LabeledExprParser.PanensContext ctx) {
        return visit(ctx.expr());
    }
}
